home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / Interfaces&Libraries / Universal / Interfaces / AIncludes / MixedMode.a < prev    next >
Encoding:
Text File  |  1998-08-17  |  13.1 KB  |  389 lines  |  [TEXT/MPS ]

  1. ;
  2. ;    File:        MixedMode.a
  3. ;
  4. ;    Contains:    Mixed Mode Manager Interfaces.
  5. ;
  6. ;    Version:    Technology:    Mac OS 8
  7. ;                Release:    Universal Interfaces 3.2
  8. ;
  9. ;    Copyright:    © 1992-1998 by Apple Computer, Inc., all rights reserved.
  10. ;
  11. ;    Bugs?:        For bug reports, consult the following page on
  12. ;                the World Wide Web:
  13. ;
  14. ;                    http://developer.apple.com/bugreporter/
  15. ;
  16. ;
  17.     IF &TYPE('__MIXEDMODE__') = 'UNDEFINED' THEN
  18. __MIXEDMODE__ SET 1
  19.  
  20.     IF &TYPE('__MACTYPES__') = 'UNDEFINED' THEN
  21.     include 'MacTypes.a'
  22.     ENDIF
  23.  
  24. ;  Mixed Mode constants 
  25. ;  Current Routine Descriptor Version 
  26.  
  27. kRoutineDescriptorVersion        EQU        7
  28. ;  MixedModeMagic Magic Cookie/Trap number 
  29.  
  30. _MixedModeMagic                    EQU        $AAFE
  31. ;  MixedModeState Version for CFM68K Mixed Mode 
  32.  
  33. kCurrentMixedModeStateRecord    EQU        1
  34. ;  Calling Conventions 
  35. ; typedef unsigned short                 CallingConventionType
  36.  
  37.  
  38. kPascalStackBased                EQU        0
  39. kCStackBased                    EQU        1
  40. kRegisterBased                    EQU        2
  41. kD0DispatchedPascalStackBased    EQU        8
  42. kD1DispatchedPascalStackBased    EQU        12
  43. kD0DispatchedCStackBased        EQU        9
  44. kStackDispatchedPascalStackBased EQU    14
  45. kThinkCStackBased                EQU        5
  46. ;  ISA Types 
  47. ; typedef SInt8                         ISAType
  48.  
  49.  
  50. kM68kISA                        EQU        0
  51. kPowerPCISA                        EQU        1
  52. ;  RTA Types 
  53. ; typedef SInt8                         RTAType
  54.  
  55.  
  56. kOld68kRTA                        EQU        $00
  57. kPowerPCRTA                        EQU        $00
  58. kCFM68kRTA                        EQU        $10
  59. ;  Constants for specifing 68k registers 
  60.  
  61. kRegisterD0                        EQU        0
  62. kRegisterD1                        EQU        1
  63. kRegisterD2                        EQU        2
  64. kRegisterD3                        EQU        3
  65. kRegisterD4                        EQU        8
  66. kRegisterD5                        EQU        9
  67. kRegisterD6                        EQU        10
  68. kRegisterD7                        EQU        11
  69. kRegisterA0                        EQU        4
  70. kRegisterA1                        EQU        5
  71. kRegisterA2                        EQU        6
  72. kRegisterA3                        EQU        7
  73. kRegisterA4                        EQU        12
  74. kRegisterA5                        EQU        13
  75. kRegisterA6                        EQU        14                    ; A7 is the same as the PowerPC SP 
  76. kCCRegisterCBit                    EQU        16
  77. kCCRegisterVBit                    EQU        17
  78. kCCRegisterZBit                    EQU        18
  79. kCCRegisterNBit                    EQU        19
  80. kCCRegisterXBit                    EQU        20
  81. ; typedef unsigned short                 registerSelectorType
  82.  
  83. ;  SizeCodes we use everywhere 
  84.  
  85. kNoByteCode                        EQU        0
  86. kOneByteCode                    EQU        1
  87. kTwoByteCode                    EQU        2
  88. kFourByteCode                    EQU        3
  89. ;  Mixed Mode Routine Records 
  90. ; typedef unsigned long                 ProcInfoType
  91.  
  92. ;  Routine Flag Bits 
  93. ; typedef unsigned short                 RoutineFlagsType
  94.  
  95.  
  96. kProcDescriptorIsAbsolute        EQU        $00
  97. kProcDescriptorIsRelative        EQU        $01
  98.  
  99. kFragmentIsPrepared                EQU        $00
  100. kFragmentNeedsPreparing            EQU        $02
  101.  
  102. kUseCurrentISA                    EQU        $00
  103. kUseNativeISA                    EQU        $04
  104.  
  105. kPassSelector                    EQU        $00
  106. kDontPassSelector                EQU        $08
  107.  
  108. kRoutineIsNotDispatchedDefaultRoutine EQU $00
  109. kRoutineIsDispatchedDefaultRoutine EQU    $10
  110.  
  111. kProcDescriptorIsProcPtr        EQU        $00
  112. kProcDescriptorIsIndex            EQU        $20
  113. RoutineRecord            RECORD 0
  114. procInfo                 ds.l    1                ; offset: $0 (0)        ;  calling conventions 
  115. reserved1                 ds.b    1                ; offset: $4 (4)        ;  Must be 0 
  116. ISA                         ds.b    1                ; offset: $5 (5)        ;  Instruction Set Architecture 
  117. routineFlags             ds.w    1                ; offset: $6 (6)        ;  Flags for each routine 
  118. procDescriptor             ds.l    1                ; offset: $8 (8)        ;  Where is the thing we’re calling? 
  119. reserved2                 ds.l    1                ; offset: $C (12)        ;  Must be 0 
  120. selector                 ds.l    1                ; offset: $10 (16)        ;  For dispatched routines, the selector 
  121. sizeof                     EQU *                    ; size:   $14 (20)
  122.                         ENDR
  123. ; typedef struct RoutineRecord *        RoutineRecordPtr
  124.  
  125. ; typedef RoutineRecordPtr *            RoutineRecordHandle
  126.  
  127. ;  Mixed Mode Routine Descriptors 
  128. ;  Definitions of the Routine Descriptor Flag Bits 
  129. ; typedef UInt8                         RDFlagsType
  130.  
  131.  
  132. kSelectorsAreNotIndexable        EQU        $00
  133. kSelectorsAreIndexable            EQU        $01
  134. ;  Routine Descriptor Structure 
  135. RoutineDescriptor        RECORD 0
  136. goMixedModeTrap             ds.w    1                ; offset: $0 (0)        ;  Our A-Trap 
  137. version                     ds.b    1                ; offset: $2 (2)        ;  Current Routine Descriptor version 
  138. routineDescriptorFlags     ds.b    1                ; offset: $3 (3)        ;  Routine Descriptor Flags 
  139. reserved1                 ds.l    1                ; offset: $4 (4)        ;  Unused, must be zero 
  140. reserved2                 ds.b    1                ; offset: $8 (8)        ;  Unused, must be zero 
  141. selectorInfo             ds.b    1                ; offset: $9 (9)        ;  If a dispatched routine, calling convention, else 0 
  142. routineCount             ds.w    1                ; offset: $A (10)        ;  Number of routines in this RD 
  143. routineRecords             ds        RoutineRecord    ; offset: $C (12) <-- really an array of length one ;  The individual routines 
  144. sizeof                     EQU *                    ; size:   $20 (32)
  145.                         ENDR
  146. ; typedef struct RoutineDescriptor *    RoutineDescriptorPtr
  147.  
  148. ; typedef RoutineDescriptorPtr *        RoutineDescriptorHandle
  149.  
  150. ;  68K MixedModeStateRecord 
  151. MixedModeStateRecord    RECORD 0
  152. state1                     ds.l    1                ; offset: $0 (0)
  153. state2                     ds.l    1                ; offset: $4 (4)
  154. state3                     ds.l    1                ; offset: $8 (8)
  155. state4                     ds.l    1                ; offset: $C (12)
  156. sizeof                     EQU *                    ; size:   $10 (16)
  157.                         ENDR
  158. ;  Mixed Mode ProcInfos 
  159.  
  160.                                                             ; Calling Convention Offsets 
  161. kCallingConventionWidth            EQU        4
  162. kCallingConventionPhase            EQU        0
  163. kCallingConventionMask            EQU        $0F                    ; Result Offsets 
  164. kResultSizeWidth                EQU        2
  165. kResultSizePhase                EQU        4
  166. kResultSizeMask                    EQU        $30                    ; Parameter offsets & widths 
  167. kStackParameterWidth            EQU        2
  168. kStackParameterPhase            EQU        6
  169. kStackParameterMask                EQU        $FFFFFFC0            ; Register Result Location offsets & widths 
  170. kRegisterResultLocationWidth    EQU        5
  171. kRegisterResultLocationPhase    EQU        6                    ; Register Parameter offsets & widths 
  172. kRegisterParameterWidth            EQU        5
  173. kRegisterParameterPhase            EQU        11
  174. kRegisterParameterMask            EQU        $7FFFF800
  175. kRegisterParameterSizePhase        EQU        0
  176. kRegisterParameterSizeWidth        EQU        2
  177. kRegisterParameterWhichPhase    EQU        2
  178. kRegisterParameterWhichWidth    EQU        3                    ; Dispatched Stack Routine Selector offsets & widths 
  179. kDispatchedSelectorSizeWidth    EQU        2
  180. kDispatchedSelectorSizePhase    EQU        6                    ; Dispatched Stack Routine Parameter offsets 
  181. kDispatchedParameterPhase        EQU        8                    ; Special Case offsets & widths 
  182. kSpecialCaseSelectorWidth        EQU        6
  183. kSpecialCaseSelectorPhase        EQU        4
  184. kSpecialCaseSelectorMask        EQU        $03F0
  185.  
  186. kSpecialCase                    EQU        $000F                ; (CallingConventionType) 
  187.  
  188.                                                             ; all of the special cases enumerated.  The selector field is 6 bits wide 
  189. kSpecialCaseHighHook            EQU        0
  190. kSpecialCaseCaretHook            EQU        0                    ; same as kSpecialCaseHighHook 
  191. kSpecialCaseEOLHook                EQU        1
  192. kSpecialCaseWidthHook            EQU        2
  193. kSpecialCaseTextWidthHook        EQU        2                    ; same as kSpecialCaseWidthHook 
  194. kSpecialCaseNWidthHook            EQU        3
  195. kSpecialCaseDrawHook            EQU        4
  196. kSpecialCaseHitTestHook            EQU        5
  197. kSpecialCaseTEFindWord            EQU        6
  198. kSpecialCaseProtocolHandler        EQU        7
  199. kSpecialCaseSocketListener        EQU        8
  200. kSpecialCaseTERecalc            EQU        9
  201. kSpecialCaseTEDoText            EQU        10
  202. kSpecialCaseGNEFilterProc        EQU        11
  203. kSpecialCaseMBarHook            EQU        12
  204.  
  205. ;    NOTES ON USING ROUTINE DESCRIPTOR FUNCTIONS
  206. ;    
  207. ;    When calling these routine from classic 68k code there are two possible intentions.
  208. ;
  209. ;    The first is source compatibility with code ported to CFM (either PowerPC or 68k CFM). When
  210. ;    the code is compiled for CFM the functions create routine descriptors that can be used by
  211. ;    the mixed mode manager operating on that machine. When the code is compiled for classic 68k
  212. ;    these functions do nothing so that the code will run on Macintoshes that do not have a
  213. ;    mixed mode manager. The dual nature of these functions is achieved by turning the CFM calls
  214. ;    into "no-op" macros for classic 68k: You can put "NewRoutineDescriptor" in your source,
  215. ;    compile it for any runtime or instruction set architecture, and it will run correctly on the
  216. ;    intended runtime/instruction platform. All without source changes and/or conditional source.
  217. ;    
  218. ;    The other intention is for code that "knows" that it is executing as classic 68k runtime
  219. ;    and is specifically trying to call code of another architecture using mixed mode. Since the
  220. ;    routines were designed with classic <-> CFM source compatibility in mind this second case
  221. ;    is treated special. For classic 68k code to create routines descriptors for use by mixed mode
  222. ;    it must call the "Trap" versions of the routines (NewRoutineDescriptorTrap). These versions
  223. ;    are only available to classic 68k callers: rigging the interfaces to allow calling them
  224. ;    from CFM code will result in runtime failure because no shared library implements or exports
  225. ;    the functions.
  226. ;    
  227. ;
  228. ;    This almost appears seamless until you consider "fat" routine descriptors and the advent of
  229. ;    CFM-68K. What does "fat" mean? CFM-68K is not emulated on PowerPC and PowerPC is not emulated
  230. ;    on CFM-68K. It makes no sense to create a routine descriptor having both a CFM-68K routine
  231. ;    and a PowerPC native routine pointer. Therefore "fat" is defined to be a mix of classic and
  232. ;    CFM for the hardware's native instruction set: on PowerPC fat is classic and PowerPC native,
  233. ;    on a 68k machine with CFM-68K installed fat is classic and CFM-68K.
  234. ;    
  235. ;    By definition fat routine descriptors are only constructed by code that is aware of the 
  236. ;    architecture it is executing as and that another architecture exists. Source compatibility
  237. ;    between code intented as pure classic and pure CFM is not an issue and so NewFatRoutineDescriptor
  238. ;    is not available when building pure classic code.
  239. ;    
  240. ;    NewFatRoutineDescriptorTrap is available to classic code on both PowerPC and CFM-68K. The
  241. ;    classic code can use the code fragment manager routine "FindSymbol" to obtain the address of 
  242. ;    a routine in a shared library and then construct a routine descriptor with both the CFM routine 
  243. ;    and classic    routine.
  244. ;
  245.  
  246.  
  247.     IF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  248. ;
  249. ; pascal UniversalProcPtr NewRoutineDescriptor(ProcPtr theProc, ProcInfoType theProcInfo, ISAType theISA)
  250. ;
  251.     IF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  252.         IMPORT_CFM_FUNCTION NewRoutineDescriptor
  253.     ENDIF
  254.  
  255. ;
  256. ; pascal void DisposeRoutineDescriptor(UniversalProcPtr theProcPtr)
  257. ;
  258.     IF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  259.         IMPORT_CFM_FUNCTION DisposeRoutineDescriptor
  260.     ENDIF
  261.  
  262. ;
  263. ; pascal UniversalProcPtr NewFatRoutineDescriptor(ProcPtr theM68kProc, ProcPtr thePowerPCProc, ProcInfoType theProcInfo)
  264. ;
  265.     IF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  266.         IMPORT_CFM_FUNCTION NewFatRoutineDescriptor
  267.     ENDIF
  268.  
  269.     ELSE
  270. ;  Note that the call to NewFatRoutineDescriptor is undefined. 
  271.     ENDIF
  272.  
  273.     IF TARGET_CPU_68K ** ¬ TARGET_RT_MAC_CFM THEN
  274. ;    The "Trap" versions of the MixedMode calls are only for classic 68K clients that 
  275. ;    want to load and use CFM based code.
  276. ;
  277.  
  278. ;
  279. ; pascal UniversalProcPtr NewRoutineDescriptorTrap(ProcPtr theProc, ProcInfoType theProcInfo, ISAType theISA)
  280. ;
  281.     IF TARGET_OS_MAC ** TARGET_CPU_68K ** ¬ TARGET_RT_MAC_CFM THEN
  282.         Macro
  283.         _NewRoutineDescriptorTrap
  284.             moveq               #0,D0
  285.             dc.w                $AA59
  286.         EndM
  287.     ELSEIF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  288.         IMPORT_CFM_FUNCTION NewRoutineDescriptorTrap
  289.     ENDIF
  290.  
  291. ;
  292. ; pascal void DisposeRoutineDescriptorTrap(UniversalProcPtr theProcPtr)
  293. ;
  294.     IF TARGET_OS_MAC ** TARGET_CPU_68K ** ¬ TARGET_RT_MAC_CFM THEN
  295.         Macro
  296.         _DisposeRoutineDescriptorTrap
  297.             moveq               #1,D0
  298.             dc.w                $AA59
  299.         EndM
  300.     ELSEIF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  301.         IMPORT_CFM_FUNCTION DisposeRoutineDescriptorTrap
  302.     ENDIF
  303.  
  304. ;
  305. ; pascal UniversalProcPtr NewFatRoutineDescriptorTrap(ProcPtr theM68kProc, ProcPtr thePowerPCProc, ProcInfoType theProcInfo)
  306. ;
  307.     IF TARGET_OS_MAC ** TARGET_CPU_68K ** ¬ TARGET_RT_MAC_CFM THEN
  308.         Macro
  309.         _NewFatRoutineDescriptorTrap
  310.             moveq               #2,D0
  311.             dc.w                $AA59
  312.         EndM
  313.     ELSEIF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  314.         IMPORT_CFM_FUNCTION NewFatRoutineDescriptorTrap
  315.     ENDIF
  316.  
  317.     ENDIF
  318.     IF TARGET_RT_MAC_CFM THEN
  319. ;    CallUniversalProc is only implemented in shared libraries on CFM68K and PowerPC, it is now
  320. ;    conditionalize with TARGET_RT_MAC_CFM.  This will catch accidental calls from classic 68K code
  321. ;    that previously only showed up as linker errors.
  322. ;
  323.  
  324.     ENDIF    ; TARGET_RT_MAC_CFM
  325.     IF TARGET_CPU_68K THEN
  326. ;
  327. ; pascal OSErr SaveMixedModeState(MixedModeStateRecord *stateStorage, UInt32 stateVersion)
  328. ;
  329.     IF TARGET_OS_MAC ** TARGET_CPU_68K ** ¬ TARGET_RT_MAC_CFM THEN
  330.         Macro
  331.         _SaveMixedModeState
  332.             moveq               #3,D0
  333.             dc.w                $AA59
  334.         EndM
  335.     ELSEIF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  336.         IMPORT_CFM_FUNCTION SaveMixedModeState
  337.     ENDIF
  338.  
  339. ;
  340. ; pascal OSErr RestoreMixedModeState(MixedModeStateRecord *stateStorage, UInt32 stateVersion)
  341. ;
  342.     IF TARGET_OS_MAC ** TARGET_CPU_68K ** ¬ TARGET_RT_MAC_CFM THEN
  343.         Macro
  344.         _RestoreMixedModeState
  345.             moveq               #4,D0
  346.             dc.w                $AA59
  347.         EndM
  348.     ELSEIF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  349.         IMPORT_CFM_FUNCTION RestoreMixedModeState
  350.     ENDIF
  351.  
  352.     ENDIF    ; TARGET_CPU_68K
  353. ;  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
  354. ; *
  355. ; *    Macros for building ProcInfos.  Examples:
  356. ; *    
  357. ; *    
  358. ; *    uppModalFilterProcInfo = kPascalStackBased
  359. ; *         | RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
  360. ; *         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DialogPtr)))
  361. ; *         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(EventRecord*)))
  362. ; *         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short*))),
  363. ; *
  364. ; *    uppDeskHookProcInfo = kRegisterBased
  365. ; *         | REGISTER_ROUTINE_PARAMETER(1, kRegisterD0, SIZE_CODE(sizeof(Boolean)))
  366. ; *         | REGISTER_ROUTINE_PARAMETER(2, kRegisterA0, SIZE_CODE(sizeof(EventRecord*)))
  367. ; *
  368. ; *    uppGXSpoolResourceProcInfo = kCStackBased
  369. ; *         | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  370. ; *         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(gxSpoolFile)))
  371. ; *         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
  372. ; *         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ResType)))
  373. ; *         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
  374. ; *
  375. ; *    uppTEFindWordProcInfo = SPECIAL_CASE_PROCINFO( 6 ),
  376. ; *
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.     ENDIF ; __MIXEDMODE__ 
  384.  
  385.